package com.github.caiqy.shirodemo.config;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.lang.Nullable;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @param <T>
 * @author caiqy
 * @date 2019 08 26
 */
public class MyRedisSerializer<T> implements RedisSerializer<T> {

    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

    private final JavaType javaType;

    /**
     * Creates a new {@link MyRedisSerializer} for the given target {@link Class}.
     *
     * @param type
     */
    public MyRedisSerializer(Class<T> type) {
        this.javaType = getJavaType(type);
    }

    /**
     * Creates a new {@link MyRedisSerializer} for the given target {@link JavaType}.
     *
     * @param javaType
     */
    public MyRedisSerializer(JavaType javaType) {
        this.javaType = javaType;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T deserialize(@Nullable byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            return (T) SerializationUtils.unserializable(bytes);
        } catch (Exception ex) {
            throw new SerializationException("Could not read: " + ex.getMessage(), ex);
        }
    }

    @Override
    public byte[] serialize(@Nullable Object t) throws SerializationException {

        if (t == null) {
            return SerializationUtils.EMPTY_ARRAY;
        }
        try {
            return SerializationUtils.serializable(t);
        } catch (Exception ex) {
            throw new SerializationException("Could not write : " + ex.getMessage(), ex);
        }
    }

    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }
}
